﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Styx.TreeSharp;
using Action = Styx.TreeSharp.Action;
using Styx.WoWInternals.WoWObjects;
using Styx.CommonBot;
using Styx;

namespace XS
{
    class XS_Hunter_Marksmanship
    {
        /* this one really is important for the sake of mankind */
        private static LocalPlayer Me { get { return XSCommon.Me; } }


        public static Composite Player(CanRunDecoratorDelegate cond)
        {
            return Boss(cond);
        }   //add pvp logic, currently only Boss(), 05-12-2012

        public static Composite Boss(CanRunDecoratorDelegate cond)
        { //boss is the same as normal, but has ~2 more cds! funny eh.
            return (
                new Decorator(
                    delegate(object a)
                    {
                        if (!cond(a))
                            return false;
                        if (Me.Specialization != WoWSpec.HunterMarksmanship)
                            return false;

                        XSCommon.writeDebug("MM, Boss");
                        return true;
                    },
                    new PrioritySelector(
                        /* Lets fire some cooldowns first, shall we? i'd like to implement a "on trinket procc / bloodlust use the force, luke" logic */

                        //Racial, if we're ork or troll we'll use our hulk-powers. if we do not already have them.
                        new Decorator(ret => !XSCommon.IsMyAuraActive("Berserking") && !XSCommon.IsMyAuraActive("Blood Fury"),
                            XSCommon.UseCooldown_Racial()
                        ),

                        XSCommon.UseCooldown_Hunter_RapidFire(),

                        XSCommon.CastSpell("Stampede", ret => XSCommon.CanCast("Stampede")),

                        //Trinket 1 and 2, we've set if we'd like to use them in our XS_Class.cs - or in our not yet available gui, HÜA
                        XSCommon.UseCooldown_Trinket(1, XS_Hunter.varTrinket1),
                        XSCommon.UseCooldown_Trinket(2, XS_Hunter.varTrinket2),

                        //Lifeblood
                        new Decorator(ret => XSCommon.IsMyAuraActive("Lifeblood"),
                            XSCommon.UseCooldown_Herbalism()
                        ),

                        //Tier 4
                        XSCommon.CastSpell("Fervor", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 3 && Me.CurrentFocus <= 60),
                        XSCommon.CastSpell("Dire Beast", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 3 && Me.CurrentFocus <= 60),

                        //Tier 5
                        XSCommon.CastSpell("A Murder of Crows", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 10),
                        XSCommon.CastSpell("Blink Strike", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 2),
                        XSCommon.CastSpell("Lynx Rush", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 5),

                        /**** PRIORITY TESTING ****/
                        new PrioritySelector(

                            //Aimed shot procc has always top priority
                            new Decorator(ret => XSCommon.IsMyAuraActive("Fire!"),
                                XSCommon.CastSpell("Aimed Shot", ret => XSCommon.IsMyAuraActive("Fire!"))
                            ),

                            //Poison
                            new Decorator(ret => XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) < 1,
                                XSCommon.CastSpell("Serpent Sting", ret => XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) < 1)
                            ),

                            //Steady focus -> steady shot, WE NEED THIS!
                            new Decorator(ret => !XSCommon.IsMyAuraActive("Steady Focus"),
                                XSCommon.CastSpell("Steady Shot", ret => true)
                            ),

                            //poison below 7s, we need to refresh. DO IT NOW, CHIMERA!
                            new Decorator(ret => XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) < 6,
                                XSCommon.CastSpell("Chimera Shot", ret => XSCommon.CanCast("Chimera Shot"))
                            ),

                            //if we have steady focus and poison is longer than/equal 7s... we shall do normal rota, well one of two.
                            new Decorator(ret => XSCommon.IsMyAuraActive("Steady Focus") && XSCommon.MyAuraTimeMilliseconds("Serpent Sting", Me.CurrentTarget) >= 6,
                                new PrioritySelector(
                                    #region >= 80
                                    new Decorator(ret => Me.CurrentTarget.HealthPercent >= 80,
                                        new PrioritySelector(
                                            //dump focus lol!
                                            XSCommon.CastSpell("Aimed Shot", ret => Me.CurrentFocus >= 60),

                                            //build focus lol!
                                            XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 60)
                                        )
                                    ),
                                    #endregion
                                    #region <80, >20
                                    new Decorator(ret => Me.CurrentTarget.HealthPercent < 80 && Me.CurrentTarget.HealthPercent > 20,
                                        new PrioritySelector(
                                            //chimera shot has priority
                                            new Decorator(ret => SpellManager.Spells["Chimera Shot"].CooldownTimeLeft.Seconds < 1,
                                                new PrioritySelector(
                                                    XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 45),
                                                    XSCommon.CastSpell("Chimera Shot", ret => XSCommon.CanCast("Chimera Shot"))
                                                )
                                            ),

                                            new Decorator(ret => SpellManager.Spells["Kill Shot"].CooldownTimeLeft.Seconds > 1,
                                                new PrioritySelector(
                                                    //Tier 6
                                                    XSCommon.CastSpell("Glaive Toss", ret => XSCommon.CanCast("Glaive Toss")),
                                                    XSCommon.CastSpell("Powershot", ret => XSCommon.CanCast("Powershot")),
                                                    XSCommon.CastSpell("Barrage", ret => XSCommon.CanCast("Barrage")),
                                        
                                                    //dump focus yay
                                                    XSCommon.CastSpell("Arcane Shot", ret => (Me.CurrentFocus >= 20 && SpellManager.Spells["Chimera Shot"].CooldownTimeLeft.Seconds > 3) || Me.CurrentFocus >= 64),
                                            
                                                    //build focus yay
                                                    XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 64)
                                                )
                                            )
                                        )
                                    ),
                                    #endregion
                                    #region <= 20
                                    new Decorator(ret => Me.CurrentTarget.HealthPercent <= 20,
                                        new PrioritySelector(
                                            
                                            XSCommon.CastSpell("Kill Shot", ret => XSCommon.CanCast("Kill Shot")),
                                        
                                            //chimera shot has priority
                                            new Decorator(ret => SpellManager.Spells["Chimera Shot"].CooldownTimeLeft.Seconds < 1,
                                                new PrioritySelector(
                                                    XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 45),
                                                    XSCommon.CastSpell("Chimera Shot", ret => XSCommon.CanCast("Chimera Shot"))
                                                )
                                            ),

                                            new Decorator(ret => SpellManager.Spells["Kill Shot"].CooldownTimeLeft.Seconds > 1,
                                                new PrioritySelector(
                                                    //Tier 6
                                                    XSCommon.CastSpell("Glaive Toss", ret => XSCommon.CanCast("Glaive Toss")),
                                                    XSCommon.CastSpell("Powershot", ret => XSCommon.CanCast("Powershot")),
                                                    XSCommon.CastSpell("Barrage", ret => XSCommon.CanCast("Barrage")),
                                        
                                                    //dump focus yay
                                                    XSCommon.CastSpell("Arcane Shot", ret => (Me.CurrentFocus >= 20 && SpellManager.Spells["Chimera Shot"].CooldownTimeLeft.Seconds > 3) || Me.CurrentFocus >= 64),
                                            
                                                    //build focus yay
                                                    XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 64)
                                                )
                                            )
                                        )
                                    )
                                    #endregion
                                )
                            )
                        )
                    )
                )
            );
        }   //done, 05-12-2012, updated 05-12-2012

        public static Composite AoE(CanRunDecoratorDelegate cond)
        {
            return (
                new Decorator(
                    delegate(object a)
                    {
                        if (!cond(a))
                            return false;
                        if (Me.Specialization != WoWSpec.HunterMarksmanship)
                            return false;

                        XSCommon.writeDebug("MM, AoE");
                        return true;
                    },
                    new PrioritySelector(
                        /* Lets fire some cooldowns first, shall we? i'd like to implement a "on trinket procc / bloodlust use the force, luke" logic */

                        //Racial, if we're ork or troll we'll use our hulk-powers. if we do not already have them.
                        new Decorator(ret => !XSCommon.IsMyAuraActive("Berserking") && !XSCommon.IsMyAuraActive("Blood Fury"),
                            XSCommon.UseCooldown_Racial()
                        ),

                        //Trinket 1 and 2, we've set if we'd like to use them in our XS_Class.cs - or in our not yet available gui, HÜA
                        XSCommon.UseCooldown_Trinket(1, XS_Hunter.varTrinket1),
                        XSCommon.UseCooldown_Trinket(2, XS_Hunter.varTrinket2),

                        //Lifeblood
                        new Decorator(ret => XSCommon.IsMyAuraActive("Lifeblood"),
                            XSCommon.UseCooldown_Herbalism()
                        ),

                        //Tier 4
                        XSCommon.CastSpell("Fervor", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 3 && Me.CurrentFocus <= 60),
                        XSCommon.CastSpell("Dire Beast", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 3 && Me.CurrentFocus <= 60),

                        //Tier 5
                        //XSCommon.CastSpell("A Murder of Crows", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 10),
                        XSCommon.CastSpell("Blink Strike", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 2),
                        XSCommon.CastSpell("Lynx Rush", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 5),

                        /**** PRIORITY TESTING ****/
                        new PrioritySelector(

                            //Aimed shot procc has always top priority
                            XSCommon.CastSpell("Aimed Shot!", ret => XSCommon.IsMyAuraActive("Fire!")),

                            new Decorator(ret => !XSCommon.IsMyAuraActive("Fire!"),
                                new PrioritySelector(
                                    new Decorator(ret => XSCommon.IsMyAuraActive("Bombardement"),
                                        new PrioritySelector(
                                            XSCommon.CastSpell("Multi-Shot", ret => Me.CurrentFocus >= 20),
                                            XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 20)
                                        )
                                    ),
                                
                                    new Decorator(ret => !XSCommon.IsMyAuraActive("Steady Focus"),
                                        XSCommon.CastSpell("Steady Shot", ret => XSCommon.CanCast("Steady Shot"))
                                    ),
                                
                                    new Decorator(ret => !XSCommon.IsMyAuraActive("Bombardement") && XSCommon.IsMyAuraActive("Steady Focus"),
                                        new PrioritySelector(
                                            //Tier 6
                                            XSCommon.CastSpell("Glaive Toss", ret => XSCommon.CanCast("Glaive Toss")),
                                            XSCommon.CastSpell("Powershot", ret => XSCommon.CanCast("Powershot")),
                                            XSCommon.CastSpell("Barrage", ret => XSCommon.CanCast("Barrage")),

                                            //Ice Trap cause I glyphed the shit!
                                            new Decorator(ret => SpellManager.Spells["Ice Trap"].CooldownTimeLeft.TotalSeconds < 1 && Me.CurrentTarget.InLineOfSight,
                                                new PrioritySelector(
                                                    XSCommon.CastSelfSpell("Trap Launcher", ret => !Me.HasAura("Trap Launcher")),
                                                    XSCommon.CastOnUnitLocation("Ice Trap", Me.CurrentTarget, ret => Me.HasAura("Trap Launcher"))
                                                )
                                            ),

                                            //Explosive Trap for AoE
                                            new Decorator(ret => !Me.CurrentTarget.IsMoving && SpellManager.Spells["Explosive Trap"].CooldownTimeLeft.TotalSeconds < 1 && Me.CurrentTarget.InLineOfSight,
                                                new PrioritySelector(
                                                    XSCommon.CastSelfSpell("Trap Launcher", ret => !Me.HasAura("Trap Launcher")),
                                                    XSCommon.CastOnUnitLocation("Explosive Trap", Me.CurrentTarget, ret => Me.HasAura("Trap Launcher"))
                                                )
                                            ),
                                    
                                            XSCommon.CastSpell("Multi-Shot", ret => XSCommon.CanCast("Multi-Shot")),

                                            XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 40)
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
            );
        }   //done, 05-12-2012, updated 05-12-2012
        
        public static Composite Normal(CanRunDecoratorDelegate cond)
        { //boss is the same as normal, but has ~2 more cds! funny eh.
            return (
                new Decorator(
                    delegate(object a)
                    {
                        if (!cond(a))
                            return false;
                        if (Me.Specialization != WoWSpec.HunterMarksmanship)
                            return false;

                        XSCommon.writeDebug("MM, Boss");
                        return true;
                    },
                    new PrioritySelector(
                /* Lets fire some cooldowns first, shall we? i'd like to implement a "on trinket procc / bloodlust use the force, luke" logic */

                        //Racial, if we're ork or troll we'll use our hulk-powers. if we do not already have them.
                        new Decorator(ret => !XSCommon.IsMyAuraActive("Berserking") && !XSCommon.IsMyAuraActive("Blood Fury"),
                            XSCommon.UseCooldown_Racial()
                        ),

                        //Trinket 1 and 2, we've set if we'd like to use them in our XS_Class.cs - or in our not yet available gui, HÜA
                        XSCommon.UseCooldown_Trinket(1, XS_Hunter.varTrinket1),
                        XSCommon.UseCooldown_Trinket(2, XS_Hunter.varTrinket2),

                        //Lifeblood
                        new Decorator(ret => XSCommon.IsMyAuraActive("Lifeblood"),
                            XSCommon.UseCooldown_Herbalism()
                        ),

                        //Tier 4
                        XSCommon.CastSpell("Fervor", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 3 && Me.CurrentFocus <= 60),
                        XSCommon.CastSpell("Dire Beast", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 3 && Me.CurrentFocus <= 60),

                        //Tier 5
                        //XSCommon.CastSpell("A Murder of Crows", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 10),
                        XSCommon.CastSpell("Blink Strike", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 2),
                        XSCommon.CastSpell("Lynx Rush", ret => XSCommon.CalculateTimeToDeath(Me.CurrentTarget) >= 5),

                        /**** PRIORITY TESTING ****/
                        new PrioritySelector(

                            //Aimed shot procc has always top priority
                            new Decorator(ret => XSCommon.IsMyAuraActive("Fire!"),
                                XSCommon.CastSpell("Aimed Shot", ret => XSCommon.IsMyAuraActive("Fire!"))
                            ),

                            //Poison
                            new Decorator(ret => XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) < 1,
                                XSCommon.CastSpell("Serpent Sting", ret => XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) < 1)
                            ),

                            //Steady focus -> steady shot, WE NEED THIS!
                            new Decorator(ret => !XSCommon.IsMyAuraActive("Steady Focus"),
                                XSCommon.CastSpell("Steady Shot", ret => true)
                            ),

                            //poison below 7s, we need to refresh. DO IT NOW, CHIMERA!
                            new Decorator(ret => XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) < 7,
                                XSCommon.CastSpell("Chimera Shot", ret => XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) < 1)
                            ),

                            //if we have steady focus and poison is longer than/equal 7s... we shall do normal rota, well one of two.
                            new Decorator(ret => XSCommon.IsMyAuraActive("Steady Focus") && XSCommon.MyAuraTime("Serpent Sting", Me.CurrentTarget) >= 7,
                                new PrioritySelector(
                                    new Decorator(ret => Me.CurrentTarget.HealthPercent >= 80,
                                        new PrioritySelector(
                                            //dump focus lol!
                                            XSCommon.CastSpell("Aimed Shot", ret => Me.CurrentFocus >= 60),

                                            //build focus lol!
                                            XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 60)
                                        )
                                    ),

                                    new Decorator(ret => Me.CurrentTarget.HealthPercent < 80,
                                        new PrioritySelector(
                                            //chimera shot has priority
                                            new Decorator(ret => SpellManager.Spells["Chimera Shot"].CooldownTimeLeft.Seconds < 1,
                                                new PrioritySelector(
                                                    XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 45),
                                                    XSCommon.CastSpell("Chimera Shot", ret => XSCommon.CanCast("Chimera Shot"))
                                                )
                                            ),

                                            XSCommon.CastSpell("Kill Shot", ret => XSCommon.CanCast("Kill Shot")),

                                            new Decorator(ret => SpellManager.Spells["Kill Shot"].CooldownTimeLeft.Seconds > 1,
                                                new PrioritySelector(
                                                    //Tier 6
                                                    XSCommon.CastSpell("Glaive Toss", ret => XSCommon.CanCast("Glaive Toss")),
                                                    XSCommon.CastSpell("Powershot", ret => XSCommon.CanCast("Powershot")),
                                                    XSCommon.CastSpell("Barrage", ret => XSCommon.CanCast("Barrage")),

                                                    //dump focus yay
                                                    XSCommon.CastSpell("Arcane Shot", ret => (Me.CurrentFocus >= 20 && SpellManager.Spells["Chimera Shot"].CooldownTimeLeft.Seconds > 3) || Me.CurrentFocus >= 64),

                                                    //build focus yay
                                                    XSCommon.CastSpell("Steady Shot", ret => Me.CurrentFocus < 64)
                                                )
                                            )
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
            );
        }   //done, 05-12-2012, updated 05-12-2012
    }
}
